package Server;


import javax.swing.*;

import org.gibello.zql.ParseException;
import org.gibello.zql.ZStatement;
import org.gibello.zql.ZqlParser;

import java.io.*;
import java.net.*;

class ClientWorker implements Runnable {
	private Socket client;
	ServerGUI fatherFrame;
	int id;
	InputStream is;
	BufferedReader br = null;
	OutputStream os;
	BufferedWriter bw = null;
	ObjectOutputStream oos = null;
	boolean ngatKetNoi = false;

	ClientWorker(Socket _client, ServerGUI _fatherFrame, BufferedReader _br, BufferedWriter _bw, int _id) 
	{
		this.client = _client;
		this.fatherFrame = _fatherFrame;
		this.br = _br;
		this.bw = _bw;
		this.id = _id;
		fatherFrame.getListDanhSachClients().themPhanTu("Client ID : " + this.id);
	}
	
	public void ngatKetNoi() throws IOException
	{
		fatherFrame.getTextAreaTrangThai().append("Đã ngắt kết nối client có port : " + client.getPort()
				+ "  với ID là : " + id + "\n");
		bw.write("disconnect");
		bw.close();
		br.close();
		fatherFrame.getListDanhSachClients().xoaPhanTu("Client ID : " + id);
		
		if (fatherFrame.getListDanhSachClients().danhSachRong())
		{
			fatherFrame.getTextAreaTrangThai().append("Chờ client kết nối...\n");
		}
	}

	public void run() 
	{
		fatherFrame.getTextAreaTrangThai().append("Đã kết nối client có port : " + client.getPort()
						+ "  với ID là : " + id + "\n");

		try 
		{
			String receivedMessage;
			int loaiTruyVan;
			do {
				try 
				{
					receivedMessage = br.readLine();
					
					if (receivedMessage.equals("quit")) 
					{
						fatherFrame.getTextAreaTrangThai().append(
								"Client có port : " + client.getPort() + " với ID là :" + id + " đã ngắt kết nối tới server\n");
						fatherFrame.getListDanhSachClients().xoaPhanTu("Client ID : " + id);
						
						if (fatherFrame.getListDanhSachClients().danhSachRong())
						{
							fatherFrame.getTextAreaTrangThai().append("Chờ client kết nối...\n");
						}
						
						break;
					}
					
					receivedMessage +=";";
					
					
					fatherFrame.getTextAreaTrangThai().append(
							"Client " + id + " gửi yêu cầu truy vấn : " + receivedMessage + "\n");
					
					loaiTruyVan = getLoaiTruyVan(receivedMessage);
					/*Xử lý select */
					if (loaiTruyVan == 1) {
						fatherFrame.setIdClient(id);
						
						ZStatement st = getStatement(is, receivedMessage);
						MyParser myParser = new MyParser(loaiTruyVan, st);
						fatherFrame.setMyParser(myParser);
						fatherFrame.xacNhanKetNoi();
						fatherFrame.xuLySelect();
					}
					/*Xử lý delete */
					if (loaiTruyVan == 4) {
						fatherFrame.setIdClient(id);
						
						ZStatement st = getStatement(is, receivedMessage);
						MyParser myParser = new MyParser(loaiTruyVan, st);
						fatherFrame.setMyParser(myParser);
						fatherFrame.xacNhanKetNoi();
						fatherFrame.xuLyDelete();
					}
					
					/*Xử lý insert */
					if (loaiTruyVan == 2)
					{
						fatherFrame.setIdClient(id);
						
						ZStatement st = getStatement(is, receivedMessage);
						MyParser myParser = new MyParser(loaiTruyVan, st);
						fatherFrame.setMyParser(myParser);
						fatherFrame.xacNhanKetNoi();
						fatherFrame.xuLyInsert();
					}
					/*Xử lý update*/
					if (loaiTruyVan == 3) {
						fatherFrame.setIdClient(id);
						
						ZStatement st = getStatement(is, receivedMessage);
						MyParser myParser = new MyParser(loaiTruyVan, st);
						fatherFrame.setMyParser(myParser);
						fatherFrame.xacNhanKetNoi();
						fatherFrame.xuLyUpdate();
					}
				} 
				catch (IOException e) 
				{
				}
			} 
			while (true);
			bw.close();
			br.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void guiBangXML(MyTable myTable) {
		try {
			os = client.getOutputStream();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			JOptionPane.showMessageDialog(fatherFrame, "Lỗi tạo os");
		}
		try {
			oos = new ObjectOutputStream(os);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(fatherFrame, "Lỗi tạo oos");
		}

		try {
			BangXML bangXML = new BangXML(myTable);
			oos.writeObject(bangXML);

		} catch (IOException e) {

			JOptionPane.showMessageDialog(fatherFrame, "Lỗi khi send table");
		}

	}

	public void guiTin(String message) {
		try {
			os = client.getOutputStream();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			JOptionPane.showMessageDialog(fatherFrame, "Lỗi tạo os");
		}
		try {
			oos = new ObjectOutputStream(os);
		} catch (IOException e) {
			JOptionPane.showMessageDialog(fatherFrame, "Lỗi tạo oos");
		}

		try {
			
			oos.writeObject(message);

		} catch (IOException e) {

			JOptionPane.showMessageDialog(fatherFrame, "Lỗi khi send tin nhắn");
		}
	}
	public int getLoaiTruyVan(String cauSQL)
	{
		try {
			is = new ByteArrayInputStream(
					cauSQL.getBytes("Cp1252"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		ZqlParser parser = new ZqlParser(is);
		try {
			ZStatement st = parser.readStatement();
		} catch (ParseException e){
			
			return -1;
		}
		cauSQL = cauSQL.toLowerCase();
		if(cauSQL.contains("select") && cauSQL.contains("from"))// câu select
			return 1;
		if(cauSQL.contains("insert into") && cauSQL.contains("values") )//câu insert
			return 2;
		if(cauSQL.contains("update") && cauSQL.contains("set") && cauSQL.contains("where"))//câu update
			return 3;
		if(cauSQL.contains("delete from") &&  cauSQL.contains("where"))//câu delete
			return 4;
		return -1;
	}
	public ZStatement getStatement(InputStream is,String cauSQL)
	{
		ZStatement st = null;
		try {
			is = new ByteArrayInputStream(
					cauSQL.getBytes("Cp1252"));
			ZqlParser parser = new ZqlParser(is);
			st = parser.readStatement();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return st;
	}
}